package aoi

import(
	//"fmt"
)

//基于网格的aoi实现

//单个网格
type Grid struct {
	r 		int32                  //行坐标
	c 		int32                  //列坐标
	aoiObjs map[AOIObject]bool     //单元格管理的所有AOI对象
	mgr    *GridMgr
	id      int
}

func (this *Grid) GetGridMgr() *GridMgr {
	return this.mgr
}

//网格管理器
type GridMgr struct {
	leftBottom Position
	rightTop   Position
	grids      [][]Grid
	w          int32
}

func NewGridMgr(leftBottom,rightTop Position,splitCount int32) *GridMgr {

	if splitCount <= 0 {
		return nil
	}

	width  := rightTop.X - leftBottom.X
	height := rightTop.Y - leftBottom.Y 
	max := width
	if height > max {
		max = height
	}

	edgeW := max/splitCount
	cCount := width/edgeW     //列数量
	if width%edgeW != 0 {
		cCount++
	}

	rCount := height/edgeW    //行数量
	if height%edgeW != 0 {
		rCount++
	}

	//fmt.Println(edgeW,cCount,rCount)

	m := &GridMgr{}
	m.leftBottom = leftBottom
	m.rightTop   = rightTop
	m.grids      = make([][]Grid,rCount)
	m.w          = edgeW
	for k,_ := range(m.grids) {
		m.grids[k] = make([]Grid,cCount)
	}

	id := 1

	for r,vr := range(m.grids) {
		for c,_ := range(vr) {
			vr[c].r   = int32(r)
			vr[c].c   = int32(c)
			vr[c].mgr = m
			vr[c].id  = id
			vr[c].aoiObjs = map[AOIObject]bool{}
			//fmt.Println(r,c,id)
			id++
		}
	}

	return m

}

func (this *GridMgr) GetGridByPos(pos *Position) *Grid {
	c := pos.X/this.w
	r := pos.Y/this.w

	if r < int32(len(this.grids)) && c < int32(len(this.grids[0])) {
		return &this.grids[r][c]
	} else {
		return nil
	}
}


//返回临近8个格子+自己总共9格
func (this *GridMgr) GetNearBy(grid *Grid) []*Grid {
	pos := [9]Position{}

	//左上
	pos[0] = Position{X:grid.c-1,Y:grid.r-1}
	//上
	pos[1] = Position{X:grid.c,Y:grid.r-1}	
	//右上
	pos[2] = Position{X:grid.c+1,Y:grid.r-1}
	//左
	pos[3] = Position{X:grid.c-1,Y:grid.r}
	//中
	pos[4] = Position{X:grid.c,Y:grid.r}
	//右
	pos[5] = Position{X:grid.c+1,Y:grid.r}	
	//左下
	pos[6] = Position{X:grid.c-1,Y:grid.r+1}	
	//下
	pos[7] = Position{X:grid.c,Y:grid.r+1}
	//右下
	pos[8] = Position{X:grid.c+1,Y:grid.r+1}

	var ret [9]*Grid

	c := 0
	for _,v := range(pos) {
		if v.Y >= 0 && v.Y < int32(len(this.grids)) && v.X >= 0 && v.X < int32(len(this.grids[0])) {
			ret[c] = &this.grids[v.Y][v.X]
			c++
		}
	}
	return ret[0:c]
}


func (this *GridMgr) GetGrids() [][]Grid {
	return this.grids
}